/*
 * Copyright！
 * 该文件由王福迎创建、编写、修改
 * 邮箱：<805447391@qq.com>
 * 版权所有！
 * 如有侵权，请联系邮箱
 * 转载请联系原作
 */

package com.sdjzu.wangfuying.disableautobrightness.base;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.view.View;
import android.widget.Toast;

import com.sdjzu.wangfuying.disableautobrightness.R;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * merge by: 805447391@qq.com
 * Created by Administrator on 2018/3/6.
 * <p>
 * depend: ButterKnife:8+
 */

@SuppressLint("Registered")
public abstract class BaseActivity extends AppCompatActivity {
    private final static String STYLE_SP_NAME = "____style_____";
    private int REQUEST_CODE_PERMISSION = 1000;
    private Unbinder unbinder = null;
    private Toast mToast = null;
    private Handler mUIHandler = new Handler(Looper.getMainLooper());
    private Thread mUiThread = mUIHandler.getLooper().getThread();
    private ViewDataBinding viewDataBinding;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // reload style
        SharedPreferences sp = getSharedPreferences(STYLE_SP_NAME, MODE_PRIVATE);
        int themeId = sp.getInt("style", R.style.AppTheme);
        getTheme().applyStyle(themeId, true);
    }

    public void setStyle(@StyleRes int styleId) {
        SharedPreferences sp = getSharedPreferences(STYLE_SP_NAME, MODE_PRIVATE);
        sp.edit().putInt("style", styleId).apply();
        recreate();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    public void setContentView(@LayoutRes int layoutResID) {
        super.setContentView(layoutResID);
        unbinder = ButterKnife.bind(this);
    }

    public <T extends ViewDataBinding> ViewDataBinding setContentViewWithDataBinding(@LayoutRes int layoutResID) {
        return this.viewDataBinding = DataBindingUtil.setContentView(this, layoutResID);
    }

    public <T extends ViewDataBinding> T getViewDataBinding(Class<T> cls) {
        return cls.cast(viewDataBinding);
    }

    @SuppressLint("ShowToast")
    protected void showToast(int desc) {
        if (mToast == null) {
            mToast = Toast.makeText(this.getApplicationContext(), desc, Toast.LENGTH_SHORT);
        } else {
            mToast.setText(desc);
        }
        mToast.show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mUIHandler.removeCallbacksAndMessages(null);
        mUIHandler = null;
        if (null != unbinder)
            unbinder.unbind();
        unbinder = null;
    }

    public void runOnUiThread(Runnable task, long duration) {
        if (task == null) return;
        mUIHandler.removeCallbacks(task);
        if ((duration > 0) || Thread.currentThread() != mUiThread) {
            mUIHandler.postDelayed(task, duration);
        } else {
            try {
                task.run();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void loopOnUiThread(final Runnable task, long delay, final long duration) {
        final Runnable wrapTask = new Runnable() {
            @Override
            public void run() {
                runOnUiThread(task);
                runOnUiThread(this, duration);
            }
        };
        runOnUiThread(wrapTask, delay);
    }

    public Handler getUIHandler() {
        return mUIHandler;
    }

    public Context getContext() {
        return this;
    }

// =================================  Permission  ========================================//

    /**
     * 检测所有的权限是否都已授权
     *
     * @param permissions array of all permissions
     * @return true is grant done, else
     */
    protected boolean checkPermissions(String[] permissions) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return true;
        }

        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(this, permission) !=
                    PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取权限集中需要申请权限的列表
     *
     * @param permissions array of permissions we need to request
     * @return a set of permissions we do not have
     */
    private List<String> getDeniedPermissions(String[] permissions) {
        List<String> needRequestPermissionList = new ArrayList<>();
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(this, permission) !=
                    PackageManager.PERMISSION_GRANTED ||
                    ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
                needRequestPermissionList.add(permission);
            }
        }
        return needRequestPermissionList;
    }

    /**
     * 请求权限
     *
     * @param permissions 请求的权限
     */
    public void requestPermission(String[] permissions) {
        if (null == permissions || checkPermissions(permissions)) {
            onPermissionSuccess();
        } else {
            List<String> needPermissions = getDeniedPermissions(permissions);
            ActivityCompat.requestPermissions(this, needPermissions.toArray(new String[needPermissions.size()]), REQUEST_CODE_PERMISSION);
        }
    }

    /**
     * 系统请求权限回调
     *
     * @param requestCode  we set a default value to request code
     * @param permissions  permissions we need to grant
     * @param grantResults a array of int, which contains grant result position by position of permissions
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_PERMISSION) {
            if (verifyPermissions(grantResults)) {
                onPermissionSuccess();
            } else {
                onPermissionFailed();
            }
        }
    }

    protected void onPermissionSuccess() {
    }

    protected void onPermissionFailed() {
        showTipsDialog();
    }

    /**
     * 确认所有的权限是否都已授权
     *
     * @param grantResults a array of int
     * @return whether we have all permissions we need
     */
    private boolean verifyPermissions(int[] grantResults) {
        for (int grantResult : grantResults) {
            if (grantResult != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    /**
     * 显示提示对话框
     */
    public void showTipsDialog() {
        new AlertDialog.Builder(this)
                .setTitle("提示信息")
                .setMessage("当前应用缺少必要权限，该功能暂时无法使用。如若需要，请单击【确定】按钮前往设置中心进行权限授权。")
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                })
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        startAppSettings();
                    }
                }).show();
    }

    /**
     * 启动当前应用设置页面
     */
    private void startAppSettings() {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivity(intent);
    }


    // ====================================== Full Screen Module =================================//
    protected void hideActionBar() {
        if (null != getSupportActionBar())
            getSupportActionBar().hide();
    }

    protected void hideNavigator() {
        View decorView = getWindow().getDecorView();
        // Hide both the navigation bar and the status bar.
        // SYSTEM_UI_FLAG_FULLSCREEN is only available on Android 4.1 and higher, but as
        // a general rule, you should design your app to hide the status bar whenever you
        // hide the navigation bar.
        @SuppressLint("InlinedApi")
        int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;

        decorView.setSystemUiVisibility(uiOptions);
        decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
            @Override
            public void onSystemUiVisibilityChange(int i) {
                View decorView = getWindow().getDecorView();
                @SuppressLint("InlinedApi")
                int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                        | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
                decorView.setSystemUiVisibility(uiOptions);
            }
        });
    }

}
